Skip to content

fix(mcp): hide hog function inputs and reject no-field exclusions - #112291

Closed
Silthus wants to merge 7 commits into
PostHog:masterfrom
Silthus:fix/mcp-validate-exclude-params
Closed

Silthus wants to merge 7 commits into
PostHog:masterfrom
Silthus:fix/mcp-validate-exclude-params

Conversation

@Silthus

@Silthus Silthus commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Warning

🟡 Merge risk: medium (merge-risk rubric)

  • The input schema of four public MCP tools loses four fields. An agent can no longer override templating per input, so the backend falls back to the template's setting or hog.
  • MCP codegen now fails on an exclude_params entry that names no field. An open PR that adds such an entry fails hogli build:openapi after it rebases.
  • Limits: the 52 removed YAML entries produce no generated diff, unit tests cover both the walker and the check, and a revert is clean.

Changes

Kind Files Lines
Production 8 +55 −62
Tests 2 +154 −0
Docs 1 +2 −1
Generated 6 +0 −148
Total 17 +211 −211
  • The four hog function tools no longer accept templating, order, bytecode or transpiled on inputs.* and mappings.*.inputs.*.
  • A * in an exclusion path now steps into dict values (additionalProperties) as well as array items.
  • MCP codegen fails when an exclude_params entry names no query parameter or request body path. The error names the tool and the entry, like the other YAML gates.
  • Path parameters do not count, because the generator never removes them.
  • An entry that names a read-only body field still passes. Orval already drops those fields, so the entry is redundant but exposes nothing.
  • The check found 52 stale entries in 6 product YAML files. They name response-only fields, path parameters, or parameters the operation does not take, so they hid nothing. This PR removes them.
  • The external_data_sources_create entries for client_secret, account_id and job_inputs go too. That serializer takes credentials in a free-form payload dict, which no exclusion can reach. The refresh and reload tools still exclude these fields, because their serializer has them.
  • Mechanical: the regenerated Zod files and the four tool schema snapshots, which only remove the fields above.

How did you test this code?

Test rationale:

  • tools/openapi-codegen/tests/exclusions.test.mjs catches * failing to remove a field from dict values, at the top level and nested under an array. The closest existing test covers array items only.
  • services/mcp/tests/unit/generate-tools.test.ts catches an exclude_params entry that names no field passing silently: a typo, a path parameter, or an inherited key such as constructor. It also checks that valid entries pass, through arrays, oneOf and dicts. No earlier test covered entry validation.
  • The seams are applyNestedExclusions and generateCategoryFile, the same loop the other YAML gates test through. Deleting the check's call from that loop fails 8 cases.

Run against an OpenAPI spec built from this branch with hogli build:openapi-schema flags:

  • Regenerated the Orval schemas and tools. The only generated diff is the removal of the four fields from the hog function tools.
  • A second regeneration on the committed branch leaves the tree clean.
  • Misspelling one entry fails the build:
Generator output with inputs.*.templatng in cdp_functions.yaml
Enabled tool "cdp-functions-create": exclude_params entry "inputs.*.templatng" names no query parameter or body field, so it hides nothing. Fix the name or remove the entry.
  • hogli ci:preflight --strict --against upstream/master passed with no failures.
  • Not run: the MCP integration and live suites, and an end-to-end tool call against a running stack.

👉 Stay up-to-date with PostHog coding conventions for a smoother review.

Release status

  • No feature flag controls this change

Docs update

  • implementing-mcp-tools.md now describes the dict wildcard and the build failure for an entry that names no field.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Agent: Claude Code, Claude Opus 5.5 (claude-opus-5-5)

  • Split out of fix(mcp): reject conflicting exclusions on shared operations #111366, which no longer touches generate-tools.ts. A duplicate search for open exclude_params PRs found none. feat(mcp): report ignored input keys and cap tool schema growth #111786 reports ignored input keys at runtime, which is a separate change.
  • The strict check came first. It surfaced 68 failing entries on master, and the hog function entries among them led to the dict wildcard fix.
  • Review: two /qa-swarm rounds, GPT-6.1 Sol (correctness, risk, design) and Claude Opus 5.5 (fresh eyes). Round 1 found inherited keys and path parameters passing the check, and an error without the tool name. Round 2 moved the tests onto the generateCategoryFile seam. All four are fixed.
  • Follow-up outside this PR: inputs.*.bytecode_contract is read-only on the server but still appears in the hog function tool input.
  • Skills invoked: /tdd, /merge-risk, /qa-swarm, /writing-pr-descriptions.
  • CodeRabbit CLI pass skipped: the CLI is signed out.
  • Public artifact: everything here derives from the repository. No session material went into the PR.

🤖 Generated with Claude Code

@trunk-io

trunk-io Bot commented Oct 6, 2026

Copy link
Copy Markdown

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@Silthus Silthus changed the title fix(mcp): hide excluded hog function inputs and reject no-op exclusions fix(mcp): hide excluded hog function inputs, reject exclusions naming no field Oct 6, 2026
@Silthus Silthus changed the title fix(mcp): hide excluded hog function inputs, reject exclusions naming no field fix(mcp): hide hog function inputs and reject no-field exclusions Oct 6, 2026
@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

📝 Walkthrough

Walkthrough

The MCP tool generator now validates configured exclusions against query parameters and request-body fields. Wildcards can traverse array items and dictionary values. Tool definitions and generated schemas reflect updated exclusions. The change also adds feature-gated email-domain APIs and MCP tools, domain-wide MAIL FROM subdomain coordination, and a simulated evaluation workflow with setup guidance.

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to c44a5

The remaining issues are bounded. Require HTTPS for approval callbacks on HTTPS sites and correct the gated workflow guidance; the token message and DNS simulation also warrant follow-up.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to c44a5

Automated email-domain setup gains scoped access, while sender settings become shared across projects. Ownership checks and user approval constrain DNS changes, but HTTP return URLs remain accepted and mixed rollout can undermine domain-wide coordination. The affected scope is principally one sending domain and its related senders, not unrestricted access to other organizations.

Retained concerns

  • Low · security · inferred: The newly enabled scoped-token and MCP path can carry an HTTP return URL into the signed Domain Connect flow. The head improves the prior session-accessible behavior by restricting the destination host, but does not require HTTPS, and the generated handler forwards redirect_uri despite guidance to omit it. Actual cleartext browser navigation depends on transport protections such as HSTS; arbitrary external-host redirection is not established.
  • Medium · reliability · inferred: The new domain-wide coordination invariant is conditional on the acting user's or project's feature evaluation rather than durable domain state. A flag-off session caller can update the same SES MAIL FROM identity without locking or propagating the label, defeating coordination for flag-on senders across projects. This preserves a legacy behavior during rollout rather than introducing a new domain-ownership bypass, but leaves shared email-authentication configuration vulnerable to control drift and incomplete rollback. Uniform domain-wide targeting would reduce this risk; production targeting was unavailable.
Security review details

Security Blast Radius

  • inferred — A permitted sender update can affect the SES identity for its sending domain and propagate MAIL FROM metadata to every matching sender in the same organization, including other projects. Creation rejects foreign-organization domain claims and propagation explicitly filters by organization. Historical duplicate domains remain unknown; cross-organization compromise is not established.

Security Findings and Attack Paths

  • inferred — The two retained findings converge on one return-path weakness: an authorized caller can supply an HTTP URL on the allowed PostHog host, the API preserves it, and the builder includes it in the signed apply query. A user following the provider flow could subsequently navigate over HTTP unless browser or deployment protections upgrade it. The base already accepted such URLs for session callers; this PR narrows destinations but introduces gated scoped-token and MCP reachability.

Trust Boundaries and Controls

  • observed — Token requests require integration scopes and feature authorization in addition to the existing management permission. Resource lookup constrains email integrations to the current project and proxy records to the current organization. Provider endpoints are allowlisted, signing is required where configured by provider policy, and missing signing credentials fail URL generation rather than silently bypassing that requirement.

Resilience and Maintainability Implications

  • inferred — Uniform shared-enabled callers benefit from domain locking, refreshed database state, conflict rejection, and sibling propagation. Mixed callers can still disagree about the authoritative label. SES uses its default MAIL FROM behavior on MX failure, so drift does not necessarily stop sending; the inspected evidence does not prove a DKIM bypass or unauthorized From-domain use.

Hardening Proposals

  • proposed — Require HTTPS for production return URLs, or omit redirect_uri from the MCP input contract when the workflow does not need a return destination. Host validation should remain in the API independently of caller guidance.
  • proposed — Make shared-domain coordination durable or enforce rollout uniformly for all writers of a domain. Include cleanup in the same lifecycle coordination and provide reconciliation for successful provider changes followed by database failure; turning off a feature should not be treated as state rollback.
🚥 Pre-merge checks | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the MCP exclusion changes and their tests, but it omits substantial email-domain setup changes in the PR, including API and email integration behavior, gated MCP tools, evaluati… Update Problem and Changes to cover the email-domain setup feature and its user-visible behavior, including the feature-flagged tools and shared MAIL FROM behavior. Correct the file and line counts, document tests for the email, API, and ev…
Full details: Description check

Explanation

The description covers the MCP exclusion changes and their tests, but it omits substantial email-domain setup changes in the PR, including API and email integration behavior, gated MCP tools, evaluations, and workflow guidance. Its change table also does not match the broader file scope, and the release status says no feature flag controls the change despite the new tools being feature-flagged.

Resolution

Update Problem and Changes to cover the email-domain setup feature and its user-visible behavior, including the feature-flagged tools and shared MAIL FROM behavior. Correct the file and line counts, document tests for the email, API, and evaluation changes, and set the release status to match the feature flag. Add the required before-and-after Mermaid flowcharts for the workflow changes. Address the reported missing screenshot or demo if the frontend changes are part of this PR.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch fix/mcp-validate-exclude-params
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@Silthus
Silthus marked this pull request as ready for review October 6, 2026 16:43
@parameterai

parameterai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Risk: Low · 1 low

Since the last review, this PR swaps the feature-flag 404 gate on the domain-connect apply-url endpoint for a scoped-credential check: proxy context is now flatly denied to token callers, email context stays flag-gated for tokens via EmailDomainAgentSetupPermission, and session users get flag-free access to both tenant-scoped resolution paths; the rest is removal of enabled: false tool entries and a cosmetic generator message. No new vulnerabilities: the context field is a ChoiceField so the != "email" check cannot be bypassed by a parser differential, both resolution paths stay team/org-scoped, and removed YAML entries exposed nothing. The one real outstanding risk is unchanged: the external-data-sources-partial-update MCP tool still lets agents pass inline credentials, which this increment again leaves unexcluded.

Sentinel reviewed fa800ed · Review settings

@pr-assigner-resolver-posthog

Copy link
Copy Markdown

👀 Auto-assigned reviewers

These soft owners were skipped because they only have minor changes here. Nothing blocks merge, so self-assign if you'd like a look:

  • @PostHog/team-warehouse-sources (products/warehouse_sources/product.yaml)
  • @PostHog/team-billing (products/billing/product.yaml)

Soft owners come from each directory's owners.yaml and each product's product.yaml (resolved nearest-file-wins). For a skipped owner, the locator is the file that decided it. Generated files and lockfiles are ignored when deciding ownership.

@sampennington
sampennington requested a review from a team October 6, 2026 16:45

Copy link
Copy Markdown
Contributor

Thanks for taking the time to contribute to PostHog! ✅ All automated hygiene checks pass:

Check Status Note
Matches PR template ✅ Title and all template sections are present and filled in
Logic changes have tests ✅ New test files cover the exclusion walker and the no-field check
Screenshot or demo N/A No frontend UI files changed

I've requested a review from the product-analytics team — they'll take a look shortly.

(resolved.operation.parameters ?? []).filter((p) => p.in === 'query').map((p) => p.name)
)
const bodySchema = resolved.operation.requestBody?.content?.['application/json']?.schema
for (const entry of config.exclude_params ?? []) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 MCP agents can still pass inline credentials via external-data-sources-partial-update

The enabled external-data-sources-partial-update tool's input schema still exposes client_secret, account_id and job_inputs (see services/mcp/src/generated/warehouse_sources/api.ts:1744-1745 and :1772, confirmed in its tool-schema snapshot), so an agent can paste a secret into chat instead of routing the user through the connect-link flow the tool's own description prescribes. The PR removed the client_secret/account_id exclusions reasoning that only refresh and reload serializers carry them, but the partial-update tool shares that serializer and has no exclude_params entry at all (products/warehouse_sources/mcp/tools.yaml:498-506), and the new check iterates config.exclude_params ?? [] — an enabled tool with no entry is never validated, so this gap cannot fail the build.

How:

  1. Build passes on this branch: the partial-update tool has no exclude_params, so assertExclusionsNameRealFields skips it entirely.
  2. The tool's input schema (generated from the serializer body at api.ts:1729-1773) includes client_secret, account_id, job_inputs.
  3. An agent rotating a credential sets client_secret inline in the partial-update call, putting the secret in chat context — the exact outcome the sibling refresh/reload exclusions exist to prevent.

Fix: Add client_secret, account_id, job_inputs to external-data-sources-partial-update's exclude_params (this also demonstrates the gate should flag enabled write tools whose bodies carry credential-shaped fields with no entry).


React with 👍 if useful or 👎 if not

@webjunkie webjunkie left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. The dict wildcard and the build check both hold up, and excludePath safely skips a missing or boolean additionalProperties.

Agent review. A person authorized the approval but did not review this text.

@tomasfarias tomasfarias left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only partial review for batch export changes, so not approval. I imagine that changes in our product fall into this:

The check found 52 stale entries in 6 product YAML files

If so, I see no blockers 👍

Copy link
Copy Markdown
Contributor

Thanks for taking the time to contribute to PostHog! We get a lot of pull requests — to help get this PR reviewed faster, we have some checks in place to help you:

Check Status Note
Matches PR template ✅ Title and all template sections are present and filled
Logic changes have tests ✅ Tests added in generate-tools.test.ts, exclusions.test.mjs, and Python test files
Included a screenshot or demo ❌ .ts files changed under products/integrations/frontend/ but no screenshot or demo found in the description

Push a change or update the description and we'll automatically re-review the PR. Once all checks are green, the team will be notified.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (4)
posthog/api/integration.py (2)

1474-1483: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Rename the denial message. Session-only access does not explain the denial.

EmailDomainAgentSetupPermission denies every scoped token while the flag is off. That includes OAuth access tokens (MCP), not only personal API keys. An MCP caller receives "This action does not support personal API key access", which is wrong for that caller. Use a neutral message, for example "This action is not available for token access yet."

Proposed fix
-    message = "This action does not support personal API key access"
+    message = "This action is not available for API token access"

Update the matching assertion in posthog/api/test/test_integration.py Line 2010.


2809-2814: 🔒 Security & Privacy | 🛡️ Detected with Advanced Tier | 🟡 Minor | ⚡ Quick win

Weak Cryptography

Reachability: External
Exploitability: Difficult
CWE: CWE-319 — Cleartext Transmission of Sensitive Information

Require HTTPS for the callback when SITE_URL is HTTPS. The validator accepts a same-host http:// URI and returns it unchanged. Domain Connect includes that URI in the signed apply URL and uses it to redirect the browser after the flow. Browsers that do not upgrade the host through HSTS can make the callback request over cleartext.

Require HTTPS for HTTPS sites
-        posthog_host = urlsplit(settings.SITE_URL).netloc
-        if redirect_uri and not url_has_allowed_host_and_scheme(redirect_uri, allowed_hosts={posthog_host}):
+        site = urlsplit(settings.SITE_URL)
+        if redirect_uri and not url_has_allowed_host_and_scheme(
+            redirect_uri, allowed_hosts={site.netloc}, require_https=site.scheme == "https"
+        ):
products/workflows/evals/simulated_email_domains.py (1)

299-304: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return NoAnswer when the name exists but lacks the requested record type.

The mail_from_label_taken setup publishes an MX record at feedback.<domain>. If the simulator receives a lookup for another type at that name, _simulated_answers reports NXDOMAIN instead of NoAnswer. Check whether any record exists for the normalized name before choosing the exception.

Suggested fix
     def answers(self, name: str, record_type: str) -> set[str]:
         with self._lock:
             return set(self._records.get((_normalize(name), record_type), set()))

+    def has_name(self, name: str) -> bool:
+        normalized = _normalize(name)
+        with self._lock:
+            return any(record_name == normalized for record_name, _ in self._records)
+
@@
     values = domains.answers(str(qname), record_type)
     if not values:
+        if domains.has_name(str(qname)):
+            raise dns.resolver.NoAnswer()
         raise dns.resolver.NXDOMAIN()
products/workflows/skills/setting-up-an-email-domain/SKILL.md (1)

14-16: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep feature-gated tools out of globally shipped workflow guidance. These files ship to every MCP client, but they depend on email tools that are not available to every client.

  • products/workflows/skills/setting-up-an-email-domain/SKILL.md#L14-L16: remove the gated workflow from the global skill or make its required tools available to every client.
  • products/workflows/skills/setting-up-an-email-domain/references/publishing-records.md#L3-L3: make this reference usable without the gated verifier or keep it with guidance available only when that tool is available.

As per path instructions: “These skills ship to every MCP client. Flag any instruction that uses a command, flag, tool, or capability not available to every MCP user: flag-gated, client-specific, or mode-specific.”

Source: Path instructions


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
  • Review profile: QUIET
  • Plan: Enterprise
  • Run ID: 0c598579-64ca-4d92-92ee-33682445dca0
📥 Commits

Reviewing files that changed from the base of the PR and between ebd59c3 and c44a531.

⛔ Files ignored due to path filters (7)
  • products/integrations/frontend/generated/api.schemas.ts is excluded by !**/generated/**
  • products/integrations/frontend/generated/api.ts is excluded by !**/generated/**
  • products/integrations/frontend/generated/api.zod.ts is excluded by !**/generated/**
  • services/mcp/src/generated/cdp_functions/api.ts is excluded by !**/generated/**
  • services/mcp/src/generated/error_tracking_alerts/api.ts is excluded by !**/generated/**
  • services/mcp/src/generated/integrations/api.ts is excluded by !**/generated/**
  • services/mcp/src/tools/generated/integrations.ts is excluded by !**/generated/**
📒 Files selected for processing (52)
  • docs/published/handbook/engineering/ai/implementing-mcp-tools.md
  • posthog/api/integration.py
  • posthog/api/integration_domain_serializers.py
  • posthog/api/test/test_integration.py
  • posthog/api/test/test_integration_domain_serializers.py
  • posthog/domain_connect.py
  • posthog/models/integration/email.py
  • posthog/models/test/integration/test_email.py
  • posthog/test/test_domain_connect.py
  • products/autoresearch/mcp/tools.yaml
  • products/batch_exports/mcp/tools.yaml
  • products/billing/mcp/tools.yaml
  • products/dashboards/mcp/tools.yaml
  • products/integrations/mcp/tools.yaml
  • products/persons/mcp/tools.yaml
  • products/posthog_ai/eval_harness/harness/services.py
  • products/posthog_ai/eval_harness/test/test_sandboxed_harness_services.py
  • products/warehouse_sources/mcp/tools.yaml
  • products/workflows/evals/__init__.py
  • products/workflows/evals/eval_email_domain_setup.py
  • products/workflows/evals/scorers.py
  • products/workflows/evals/seeders.py
  • products/workflows/evals/simulated_email_domains.py
  • products/workflows/evals/test/__init__.py
  • products/workflows/evals/test/test_scorers.py
  • products/workflows/evals/test/test_simulated_email_domains.py
  • products/workflows/package.json
  • products/workflows/skills/setting-up-an-email-domain/SKILL.md
  • products/workflows/skills/setting-up-an-email-domain/references/publishing-records.md
  • services/mcp/schema/generated-tool-definitions.json
  • services/mcp/schema/tool-definitions-all.json
  • services/mcp/schema/tool-inputs.json
  • services/mcp/scripts/generate-orval-schemas.mjs
  • services/mcp/scripts/generate-tools.ts
  • services/mcp/scripts/lib/definitions.mjs
  • services/mcp/src/api/generated.ts
  • services/mcp/src/schema/tool-inputs.ts
  • services/mcp/tests/unit/__snapshots__/tool-schemas/cdp-functions-create.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/cdp-functions-partial-update.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/error-tracking-alerts-create.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/error-tracking-alerts-partial-update.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/integrations-domain-connect-apply-url-create.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/integrations-domain-connect-check-retrieve.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/integrations-email-create.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/integrations-email-partial-update.json
  • services/mcp/tests/unit/__snapshots__/tool-schemas/integrations-email-verify-create.json
  • services/mcp/tests/unit/generate-tools.test.ts
  • services/mcp/tests/unit/integrations-domain-connect-apply-url.test.ts
  • services/mcp/tests/unit/tool-definitions.test.ts
  • services/mcp/tests/unit/tool-filtering.test.ts
  • tools/openapi-codegen/src/exclusions.mjs
  • tools/openapi-codegen/tests/exclusions.test.mjs
💤 Files with no reviewable changes (12)
  • products/workflows/evals/init.py
  • products/workflows/evals/test/init.py
  • products/persons/mcp/tools.yaml
  • services/mcp/tests/unit/snapshots/tool-schemas/error-tracking-alerts-partial-update.json
  • products/warehouse_sources/mcp/tools.yaml
  • services/mcp/tests/unit/snapshots/tool-schemas/cdp-functions-create.json
  • products/dashboards/mcp/tools.yaml
  • products/billing/mcp/tools.yaml
  • services/mcp/tests/unit/snapshots/tool-schemas/error-tracking-alerts-create.json
  • products/autoresearch/mcp/tools.yaml
  • services/mcp/tests/unit/snapshots/tool-schemas/cdp-functions-partial-update.json
  • products/batch_exports/mcp/tools.yaml

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Silthus and others added 7 commits October 7, 2026 11:28
SES stores the MAIL FROM subdomain on the domain identity, so every sender
on a domain shares it. Creating a sender with a different label moved it in
SES for every sender on the domain, which only the admin-gated update route
should do.

Create now reuses the domain's label when the request omits it, and rejects
a different label with a 400 before SES is called. Update writes the new
label to every sender on the domain in the organization, so their stored
config stays in step with SES.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A misspelled or stale `exclude_params` entry was a silent no-op, so the
field it meant to hide stayed in the tool input. The generator now fails
when an entry names no query parameter or request body path.

The check found 51 entries that name read-only response fields or
parameters the operation does not take. They hid nothing, so removing
them leaves every generated tool schema unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Silthus
Silthus force-pushed the fix/mcp-validate-exclude-params branch from c44a531 to fa800ed Compare October 7, 2026 11:46
@sampennington
sampennington requested a review from a team October 7, 2026 11:48

Copy link
Copy Markdown
Contributor

Thanks for taking the time to contribute to PostHog! ✅ All automated hygiene checks pass:

Check Status Note
Matches PR template ✅ Title format correct; Problem, Changes, and How did you test sections all filled in
Logic changes have tests ✅ Tests added in exclusions.test.mjs and generate-tools.test.ts
Screenshot or demo N/A Frontend-path files changed are auto-generated API types with no visual UI impact

I've requested a review from the product-analytics team — they'll take a look shortly.

@Silthus

Silthus commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Note

🤖 GPT-6.1 Sol responding on behalf of Michael

Replaced by the draft fork PR #346 in its native fork stack. @meikelmosby will start migrating the stack from the fork into PostHog/posthog for upstream review and CI. Closing this master-targeted copy to keep the handoff clear.

@Silthus Silthus closed this Oct 7, 2026
@Silthus

Silthus commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #115571, rebased on current master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants